﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections;
using V2TEK.NET.SH.Silverlight.Charts.Core.Schedule;

namespace V2TEK.NET.SH.Silverlight.Charts.TimeLineHelper
{
    public static class DateTimeRangeDescriptorUtil
    {
        private static Dictionary<IDateTimeDescriptor, int> _defaultDateTimeRangeDescriptor;
        private static Dictionary<IDateTimeDescriptor, int> _defaultDateTimeRangeDescriptor2;

        public static Dictionary<IDateTimeDescriptor, int> DefaultDateTimeRangeDescriptor
        {
            get
            {
                if (_defaultDateTimeRangeDescriptor == null)
                {
                    _defaultDateTimeRangeDescriptor = new Dictionary<IDateTimeDescriptor, int>();
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(1, DateTimeType.Minute), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(5, DateTimeType.Minute), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(10, DateTimeType.Minute), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(15, DateTimeType.Minute), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(30, DateTimeType.Minute), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(1, DateTimeType.Hour), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(2, DateTimeType.Hour), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(6, DateTimeType.Hour), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(12, DateTimeType.Hour), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(1, DateTimeType.WeekDay), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(2, DateTimeType.Day), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(4, DateTimeType.Day), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(7, DateTimeType.Day), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(1, DateTimeType.Month), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(1, DateTimeType.Quarter), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(2, DateTimeType.Quarter), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(1, DateTimeType.Year), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(2, DateTimeType.Year), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(5, DateTimeType.Year), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(10, DateTimeType.Year), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(20, DateTimeType.Year), 0);
                    _defaultDateTimeRangeDescriptor.Add(new SimpleDateTimeDescriptor(50, DateTimeType.Year), 0);
                }
                return _defaultDateTimeRangeDescriptor;
            }
        }

        public static Dictionary<IDateTimeDescriptor, int> DefaultDateTimeRangeDescriptor2
        {
            get
            {
                if (_defaultDateTimeRangeDescriptor2 == null)
                {
                    _defaultDateTimeRangeDescriptor2 = new Dictionary<IDateTimeDescriptor, int>();
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(1, DateTimeType.Minute), 1); //-------0
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(5, DateTimeType.Minute), 1);//-------1
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(10, DateTimeType.Minute), 3);//-------2
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(15, DateTimeType.Minute), 2);//-------3
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(30, DateTimeType.Minute), 1);//-------4
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(1, DateTimeType.Hour), 2);//-------5
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(2, DateTimeType.Hour), 1);//-------6
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(6, DateTimeType.Hour), 2);//-------7
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(12, DateTimeType.Hour), 1);//-------8
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(1, DateTimeType.Day), 3);//-------9
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(2, DateTimeType.Day), 3);//-------10
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(4, DateTimeType.Day), 2);//-------11
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(1, DateTimeType.Week), 1);//-------12
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(1, DateTimeType.Month), 1);//-------14
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(1, DateTimeType.Quarter), 2);//-------15
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(2, DateTimeType.Quarter), 1);//-------16
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(1, DateTimeType.Year), 1);//-------18
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(2, DateTimeType.Year), 1);//-------19
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(5, DateTimeType.Year), 1);//-------20
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(10, DateTimeType.Year), 1);//-------21
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(20, DateTimeType.Year), 1);//-------22
                    _defaultDateTimeRangeDescriptor2.Add(new SimpleDateTimeDescriptor2(50, DateTimeType.Year), 0);//-------22
                }
                return _defaultDateTimeRangeDescriptor2;
            }
        }

        public static IDateTimeDescriptor GetDateTimeRangeDescriptor(Dictionary<IDateTimeDescriptor, int> dateTimeDescriptor, double milliDateTimeRageWidth, double zoom)
        {
            double range = 0d;

            IDateTimeDescriptor lastKey = null;

            int i = 0;
            foreach(KeyValuePair<IDateTimeDescriptor,int> keyValue in dateTimeDescriptor)
            {
                range = keyValue.Key.DateTimeRange.TotalMilliseconds;
                if (range / zoom >= milliDateTimeRageWidth)
                {
                    int refKeyIndex = keyValue.Value;

                    //如果不需要跳针，使用当前的Descriptor，如果需要，则按照针数索引至需要显示的。一般用在两级Timeline上
                    if (refKeyIndex == 0)
                        return keyValue.Key;
                    else
                    {
                        int count = dateTimeDescriptor.Values.Count;
                        IDateTimeDescriptor[] descriptors = new IDateTimeDescriptor[count];
                        dateTimeDescriptor.Keys.CopyTo(descriptors, 0);
                        if ((i + refKeyIndex) > count)
                        {
                            lastKey = descriptors[count];
                            continue;
                        }
                        else
                            return descriptors[i + refKeyIndex];
                    }
                }
                lastKey = keyValue.Key;
                i++;
            }

            return lastKey;
        }

        public static IDateTimeDescriptor GetDateTimeRangeDescriptor(double milliDateTimeRageWidth, double zoom)
        {
            return GetDateTimeRangeDescriptor(DefaultDateTimeRangeDescriptor,milliDateTimeRageWidth, zoom);
        }

        public static double GetNextZoom(Dictionary<IDateTimeDescriptor, int> dateTimeDescriptor, double milliDateTimeRageWidth, double currentZoom)
        {
            double range = 0d;

            IEnumerator<IDateTimeDescriptor> dtds = dateTimeDescriptor.Keys.GetEnumerator();
            IDateTimeDescriptor lastKey = null;

            while (dtds.MoveNext())
            {
                lastKey = dtds.Current;
                range = lastKey.DateTimeRange.TotalMilliseconds;
                if (range / currentZoom >= milliDateTimeRageWidth)
                {
                    if (dtds.MoveNext())
                    {
                        range = dtds.Current.DateTimeRange.TotalMilliseconds;
                    }
                    break;
                }
            }
            return range / milliDateTimeRageWidth;
        }

        public static double GetPreZoom(Dictionary<IDateTimeDescriptor, int> dateTimeDescriptor, double milliDateTimeRageWidth, double currentZoom)
        {
            double range = 0d;
            double preRange = 0d;

            IEnumerator<IDateTimeDescriptor> dtds = dateTimeDescriptor.Keys.GetEnumerator();
            if (dtds.MoveNext())
            {
                preRange = dtds.Current.DateTimeRange.TotalMilliseconds;
            }

            do
            {
                range = dtds.Current.DateTimeRange.TotalMilliseconds;
                if (range / currentZoom >= milliDateTimeRageWidth)
                {
                    break;
                }
                preRange = range;
            }
            while (dtds.MoveNext());

            return preRange / milliDateTimeRageWidth;
        }

        public static double GetZoomToIndex(Dictionary<IDateTimeDescriptor, int> dateTimeDescriptor, double milliDateTimeRageWidth, int index)
        {
            double range = 0d;

            IEnumerator<IDateTimeDescriptor> dtds = dateTimeDescriptor.Keys.GetEnumerator();
            IDateTimeDescriptor lastKey = null;

            int i = 0;
            do
            {
                lastKey = dtds.Current;
                range = lastKey.DateTimeRange.TotalMilliseconds;
                i++;
            }
            while (dtds.MoveNext() && i <= index);

            return range / milliDateTimeRageWidth;
        }
    }
}
